home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / include / incl98.zoo / math-68881.h < prev    next >
C/C++ Source or Header  |  1994-02-22  |  11KB  |  604 lines

  1. /******************************************************************\
  2. *                                   *
  3. *  <math-68881.h>        last modified: 23 May 1992.       *
  4. *                                   *
  5. *  Copyright (C) 1989 by Matthew Self.                   *
  6. *  You may freely distribute verbatim copies of this software       *
  7. *  provided that this copyright notice is retained in all copies.  *
  8. *  You may distribute modifications to this software under the     *
  9. *  conditions above if you also clearly note such modifications    *
  10. *  with their author and date.                               *
  11. *                                   *
  12. *  Note:  errno is not set to EDOM when domain errors occur for    *
  13. *  most of these functions.  Rather, it is assumed that the       *
  14. *  68881's OPERR exception will be enabled and handled           *
  15. *  appropriately by the    operating system.  Similarly, overflow       *
  16. *  and underflow do not set errno to ERANGE.               *
  17. *                                   *
  18. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  19. *                                   *
  20. \******************************************************************/
  21.  
  22. /* This file is NOT a part of GCC, just distributed with it.  */
  23.  
  24. /* If you find this in GCC,
  25.    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
  26.  
  27. /* Changed by Richard Stallman:
  28.    May 1993, add conditional to prevent multiple inclusion.
  29.    % inserted before a #.
  30.    New function `hypot' added.
  31.    Nans written in hex to avoid 0rnan.
  32.    May 1992, use %! for fpcr register.  Break lines before function names.
  33.    December 1989, add parens around `&' in pow.
  34.    November 1990, added alternate definition of HUGE_VAL for Sun.  */
  35.  
  36. #ifndef __math_68881
  37. #define __math_68881
  38.  
  39. #include <errno.h>
  40.  
  41. #ifdef __cplusplus
  42. extern "C" {
  43. #endif
  44.  
  45. #ifndef HUGE_VAL
  46. #ifdef __sun__
  47. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  48. #define HUGE_VAL                            \
  49. ({                                    \
  50.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  51.   u.d;                                    \
  52. })
  53. #else
  54. #define HUGE_VAL                            \
  55. ({                                    \
  56.   double huge_val;                            \
  57.                                     \
  58.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  59.      : "=f" (huge_val)                        \
  60.      : /* no inputs */);                        \
  61.   huge_val;                                \
  62. })
  63. #endif
  64. #endif
  65.  
  66. #if __GNUC__ > 2 || __GCC_MINOR__ >= 5
  67. #define __const_attribute __attribute ((const))
  68. #else
  69. #define __const_attribute
  70. #endif
  71.  
  72. __inline static double
  73. sin (double x) __const_attribute;
  74. __inline static double
  75. sin (double x)
  76. {
  77.   double value;
  78.  
  79.   __asm ("fsin%.x %1,%0"
  80.      : "=f" (value)
  81.      : "f" (x));
  82.   return value;
  83. }
  84.  
  85. __inline static double
  86. cos (double x) __const_attribute;
  87. __inline static double
  88. cos (double x)
  89. {
  90.   double value;
  91.  
  92.   __asm ("fcos%.x %1,%0"
  93.      : "=f" (value)
  94.      : "f" (x));
  95.   return value;
  96. }
  97.  
  98. __inline static double
  99. tan (double x) __const_attribute;
  100. __inline static double
  101. tan (double x)
  102. {
  103.   double value;
  104.  
  105.   __asm ("ftan%.x %1,%0"
  106.      : "=f" (value)
  107.      : "f" (x));
  108.   return value;
  109. }
  110.  
  111. __inline static double
  112. asin (double x) __const_attribute;
  113. __inline static double
  114. asin (double x)
  115. {
  116.   double value;
  117.  
  118.   __asm ("fasin%.x %1,%0"
  119.      : "=f" (value)
  120.      : "f" (x));
  121.   return value;
  122. }
  123.  
  124. __inline static double
  125. acos (double x) __const_attribute;
  126. __inline static double
  127. acos (double x)
  128. {
  129.   double value;
  130.  
  131.   __asm ("facos%.x %1,%0"
  132.      : "=f" (value)
  133.      : "f" (x));
  134.   return value;
  135. }
  136.  
  137. __inline static double
  138. atan (double x) __const_attribute;
  139. __inline static double
  140. atan (double x)
  141. {
  142.   double value;
  143.  
  144.   __asm ("fatan%.x %1,%0"
  145.      : "=f" (value)
  146.      : "f" (x));
  147.   return value;
  148. }
  149.  
  150. __inline static double
  151. atan2 (double y, double x) __const_attribute;
  152. __inline static double
  153. atan2 (double y, double x)
  154. {
  155.   double pi, pi_over_2;
  156.  
  157.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  158.      : "=f" (pi)
  159.      : /* no inputs */ );
  160.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  161.      : "=f" (pi_over_2)
  162.      : "0" (pi));
  163.   if (x > 0)
  164.     {
  165.       if (y > 0)
  166.     {
  167.       if (x > y)
  168.         return atan (y / x);
  169.       else
  170.         return pi_over_2 - atan (x / y);
  171.     }
  172.       else
  173.     {
  174.       if (x > -y)
  175.         return atan (y / x);
  176.       else
  177.         return - pi_over_2 - atan (x / y);
  178.     }
  179.     }
  180.   else
  181.     {
  182.       if (y < 0)
  183.     {
  184.       if (-x > -y)
  185.         return - pi + atan (y / x);
  186.       else
  187.         return - pi_over_2 - atan (x / y);
  188.     }
  189.       else
  190.     {
  191.       if (-x > y)
  192.         return pi + atan (y / x);
  193.       else if (y > 0)
  194.         return pi_over_2 - atan (x / y);
  195.       else
  196.         {
  197.           double value;
  198.  
  199.           errno = EDOM;
  200.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  201.              : "=f" (value)
  202.              : /* no inputs */);
  203.           return value;
  204.         }
  205.     }
  206.     }
  207. }
  208.  
  209. __inline static double
  210. sinh (double x) __const_attribute;
  211. __inline static double
  212. sinh (double x)
  213. {
  214.   double value;
  215.  
  216.   __asm ("fsinh%.x %1,%0"
  217.      : "=f" (value)
  218.      : "f" (x));
  219.   return value;
  220. }
  221.  
  222. __inline static double
  223. cosh (double x) __const_attribute;
  224. __inline static double
  225. cosh (double x)
  226. {
  227.   double value;
  228.  
  229.   __asm ("fcosh%.x %1,%0"
  230.      : "=f" (value)
  231.      : "f" (x));
  232.   return value;
  233. }
  234.  
  235. __inline static double
  236. tanh (double x) __const_attribute;
  237. __inline static double
  238. tanh (double x)
  239. {
  240.   double value;
  241.  
  242.   __asm ("ftanh%.x %1,%0"
  243.      : "=f" (value)
  244.      : "f" (x));
  245.   return value;
  246. }
  247.  
  248. __inline static double
  249. atanh (double x) __const_attribute;
  250. __inline static double
  251. atanh (double x)
  252. {
  253.   double value;
  254.  
  255.   __asm ("fatanh%.x %1,%0"
  256.      : "=f" (value)
  257.      : "f" (x));
  258.   return value;
  259. }
  260.  
  261. __inline static double
  262. exp (double x) __const_attribute;
  263. __inline static double
  264. exp (double x)
  265. {
  266.   double value;
  267.  
  268.   __asm ("fetox%.x %1,%0"
  269.      : "=f" (value)
  270.      : "f" (x));
  271.   return value;
  272. }
  273.  
  274. __inline static double
  275. expm1 (double x) __const_attribute;
  276. __inline static double
  277. expm1 (double x)
  278. {
  279.   double value;
  280.  
  281.   __asm ("fetoxm1%.x %1,%0"
  282.      : "=f" (value)
  283.      : "f" (x));
  284.   return value;
  285. }
  286.  
  287. __inline static double
  288. log (double x) __const_attribute;
  289. __inline static double
  290. log (double x)
  291. {
  292.   double value;
  293.  
  294.   __asm ("flogn%.x %1,%0"
  295.      : "=f" (value)
  296.      : "f" (x));
  297.   return value;
  298. }
  299.  
  300. __inline static double
  301. log1p (double x) __const_attribute;
  302. __inline static double
  303. log1p (double x)
  304. {
  305.   double value;
  306.  
  307.   __asm ("flognp1%.x %1,%0"
  308.      : "=f" (value)
  309.      : "f" (x));
  310.   return value;
  311. }
  312.  
  313. __inline static double
  314. log10 (double x) __const_attribute;
  315. __inline static double
  316. log10 (double x)
  317. {
  318.   double value;
  319.  
  320.   __asm ("flog10%.x %1,%0"
  321.      : "=f" (value)
  322.      : "f" (x));
  323.   return value;
  324. }
  325.  
  326. __inline static double
  327. sqrt (double x) __const_attribute;
  328. __inline static double
  329. sqrt (double x)
  330. {
  331.   double value;
  332.  
  333.   __asm ("fsqrt%.x %1,%0"
  334.      : "=f" (value)
  335.      : "f" (x));
  336.   return value;
  337. }
  338.  
  339. __inline static double
  340. hypot (const double x, const double y) __const_attribute;
  341. __inline static double
  342. hypot (const double x, const double y)
  343. {
  344. #if 0
  345.   return sqrt (x*x + y*y);
  346. #else
  347.   double value;
  348.  
  349.   __asm ("fsqrt%.x %1,%0"
  350.      : "=f" (value)
  351.      : "f" (x*x + y*y));
  352.   return value;
  353. #endif
  354. }
  355.  
  356. __inline static double
  357. pow (const double x, const double y) __const_attribute;
  358. __inline static double
  359. pow (const double x, const double y)
  360. {
  361.   if (x > 0)
  362.     return exp (y * log (x));
  363.   else if (x == 0)
  364.     {
  365.       if (y > 0)
  366.     return 0.0;
  367.       else
  368.     {
  369.       double value;
  370.  
  371.       errno = EDOM;
  372.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  373.          : "=f" (value)
  374.          : /* no inputs */);
  375.       return value;
  376.     }
  377.     }
  378.   else
  379.     {
  380.       double temp;
  381.  
  382.       __asm ("fintrz%.x %1,%0"
  383.          : "=f" (temp)            /* integer-valued float */
  384.          : "f" (y));
  385.       if (y == temp)
  386.         {
  387.       int i = (int) y;
  388.       
  389.       if ((i & 1) == 0)            /* even */
  390.         return exp (y * log (-x));
  391.       else
  392.         return - exp (y * log (-x));
  393.         }
  394.       else
  395.         {
  396.       double value;
  397.  
  398.       errno = EDOM;
  399.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  400.          : "=f" (value)
  401.          : /* no inputs */);
  402.       return value;
  403.         }
  404.     }
  405. }
  406.  
  407. __inline static double
  408. fabs (double x) __const_attribute;
  409. __inline static double
  410. fabs (double x)
  411. {
  412.   double value;
  413.  
  414.   __asm ("fabs%.x %1,%0"
  415.      : "=f" (value)
  416.      : "f" (x));
  417.   return value;
  418. }
  419.  
  420. __inline static double
  421. ceil (double x) __const_attribute;
  422. __inline static double
  423. ceil (double x)
  424. {
  425.   int rounding_mode, round_up;
  426.   double value;
  427.  
  428.   __asm volatile ("fmove%.l %!,%0"
  429.           : "=dm" (rounding_mode)
  430.           : /* no inputs */ );
  431.   round_up = rounding_mode | 0x30;
  432.   __asm volatile ("fmove%.l %0,%!"
  433.           : /* no outputs */
  434.           : "dmi" (round_up));
  435.   __asm volatile ("fint%.x %1,%0"
  436.           : "=f" (value)
  437.           : "f" (x));
  438.   __asm volatile